//
// Created by root on 19-7-29.
//

#include "method_utils.h"
#include "log_utils.h"

#define TAG "MethodUtils"

jmethodID get_method_by_name(JNIEnv *env, jclass def_class, std::string method_name_str) {
    if(!def_class){
        LOGE("def_class is nullptr\n");
        return nullptr;
    }
    const char* method_name=method_name_str.c_str();
    jclass class_class=env->FindClass("java/lang/Class");
    //public Method[] getDeclaredMethods()
    jmethodID get_decl_methods=env->GetMethodID(class_class,"getDeclaredMethods","()[Ljava/lang/reflect/Method;");
    jobjectArray methods=(jobjectArray)env->CallObjectMethod(def_class,get_decl_methods);
    int method_count=env->GetArrayLength(methods);
    jclass method_class=env->FindClass("java/lang/reflect/Method");
    //public String getName()
    jmethodID get_method_name=env->GetMethodID(method_class,"getName","()Ljava/lang/String;");
    for (int i = 0; i < method_count; ++i) {
        jobject method=env->GetObjectArrayElement(methods,i);
        jstring method_name_=(jstring)env->CallObjectMethod(method,get_method_name);
        const char* c_method_name=env->GetStringUTFChars(method_name_, nullptr);
        if(strcmp(c_method_name,method_name)==0){
            jmethodID method_id=env->FromReflectedMethod(method);
            LOGD("found method:%s -> jmethodID:%p\n",method_name,method_id);
            return method_id;//暂时不考虑重载
        }
        //循环最后必须回收资源
        env->ReleaseStringUTFChars(method_name_,c_method_name);
        env->DeleteLocalRef(method_name_);
        env->DeleteLocalRef(method);
    }
    LOGE("fail to find method:%s in class:%p\n",method_name,def_class);
    return nullptr;
}


